package com.moli.java.file;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.file.*;
import java.security.MessageDigest;
import java.util.*;

@RestController
@RequestMapping("/upload")
public class FileUploadController {
    @Autowired
    private RedisTemplate redisTemplate;

    private static final String FILE_DIR = "F:\\Saved Pictures\\";
    private static final String REDIS_KEY = "verify_";

    // 文件秒传：通过MD5验证文件是否已经上传
    @PostMapping("/verify")
    public String verifyFile(@RequestParam("fileHash") String fileHash) {
        String url = String.valueOf(redisTemplate.opsForValue().get(REDIS_KEY + fileHash));
        File file = new File(url);
        if (file.exists()) {
            return "File already uploaded!";
        } else {
            return "File not uploaded yet!";
        }
    }

    // 上传文件分片
    @PostMapping("/chunk")
    public String uploadChunk(
            @RequestParam("file") MultipartFile file,
            @RequestParam("fileHash") String fileHash,
            @RequestParam("chunkIndex") int chunkIndex,
            @RequestParam("totalChunks") int totalChunks) {

        try {
            // 保存文件分片
            // 先判断当前分片是否上传过了，如果上传过，则跳过
            Path chunkPath = Paths.get(FILE_DIR + fileHash + "_" + chunkIndex);
            if (Files.exists(chunkPath)) {
                return "Chunk already uploaded";
            }
            file.transferTo(chunkPath);

            // 如果是最后一个分片，通知客户端可以合并
            if (chunkIndex == totalChunks - 1) {
                return "Last chunk uploaded";
            } else {
                return "Chunk uploaded successfully";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "Error uploading chunk";
        }
    }

    // 合并文件分片
    @PostMapping("/merge")
    public String mergeChunks(@RequestParam("fileHash") String fileHash, @RequestParam("totalChunks") int totalChunks) {
        try {
            // 合并文件分片
            FileOutputStream outputStream = new FileOutputStream(FILE_DIR + fileHash);
            for (int i = 0; i < totalChunks; i++) {
                Path chunkPath = Paths.get(FILE_DIR + fileHash + "_" + i);
                Files.copy(chunkPath, outputStream);
                Files.delete(chunkPath); // 删除分片文件
            }
            outputStream.close();
            redisTemplate.opsForValue().set(REDIS_KEY + fileHash, FILE_DIR + fileHash);
            return "File merged successfully";
        } catch (IOException e) {
            e.printStackTrace();
            return "Error merging chunks";
        }
    }

    // 计算文件的MD5
    private String calculateMD5(File file) throws Exception {
        MessageDigest md5Digest = MessageDigest.getInstance("MD5");
        try (InputStream inputStream = new FileInputStream(file)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                md5Digest.update(buffer, 0, bytesRead);
            }
        }
        byte[] hashBytes = md5Digest.digest();
        StringBuilder hexString = new StringBuilder();
        for (byte b : hashBytes) {
            hexString.append(String.format("%02x", b));
        }
        return hexString.toString();
    }
}
